package com.silverbox.sweeporder.controller.auth;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Formatter;
import java.util.HashMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.silverbox.core.util.HttpUtil;
import com.silverbox.sweeporder.service.redis.RedisService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.fastjson.JSONObject;
import com.silverbox.core.result.CoreResponse;
import com.silverbox.core.util.HttpUtils;
import com.silverbox.core.util.StringUtils;
import com.silverbox.core.util.Utils;
import com.silverbox.sweeporder.controller.index.IndexController;
import com.silverbox.sweeporder.service.index.AuthService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * 老版本H5支付宝授权回调后重新跳转到新版本
 * @date 2017年12月6日
 * @description
 */
@Controller
@RequestMapping("alipay")
@Api(tags = { "用于用户授权" })
public class AuthController {
	
	private static Logger logger = LoggerFactory.getLogger(AuthController.class);

	@Value("${sweepOrderVueUrl}")
	private String sweepOrderVueUrl;
	
	@Value("${ALIPAY_OPEN_AUTH_URL}")
	private String ALIPAY_OPEN_AUTH_URL;
	
	@Value("${auth.url}")
	private String authUrl;
	
	@Autowired
	private AuthService authService;
	@Autowired
    private RedisService redisService;

	/**
	 * 扫码下单老板授权回调后地址
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = { "/redirectPath" })
    @ResponseBody
	public void redirectPath(HttpServletRequest request,
			HttpServletResponse response) {
		Integer tableInfoId = StringUtils.isEmpty(request.getParameter("tableInfoId")) ? null
				: Integer.valueOf(request.getParameter("tableInfoId"));
		//绑定类型
        String bindTypeStr = request.getParameter("bindType");
        Integer bindType = StringUtils.isNotEmpty(bindTypeStr) ? Integer.valueOf(bindTypeStr) : null;
		//子店铺id
		String storeId = request.getParameter("storeId");
		//主店铺id
		String shopperId = request.getParameter("shopperId");
		//顾客id
		String buyerId = request.getParameter("buyerId");
		//商品id
		String goodsId = request.getParameter("goodsId");
		//商品规格id
		String sizeId = request.getParameter("sizeId");
		//来源时支付宝 1、微信 2
		String authMode = request.getParameter("authMode");
		//微信授权后的accessToken
		String accessToken = request.getParameter("accessToken");
		String pathUrl = sweepOrderVueUrl+"/#/?buyerId=" + buyerId + "&tableInfoId=" + tableInfoId + "&storeId=" + storeId +"&md=2";
		// 预约核销配置
		String reserveHexiao = request.getParameter("reserveHexiao");
		//扫商品二维码进入商品详情页或购物车页入口
		if(StringUtils.isNotEmpty(goodsId) && StringUtils.isNotEmpty(storeId) && StringUtils.isNotEmpty(buyerId)){
			try {
				pathUrl = authService.getGoodsShowPath(Integer.valueOf(storeId), Integer.valueOf(goodsId),
						StringUtils.isEmpty(sizeId) ? null : Long.valueOf(sizeId), buyerId,
						StringUtils.isEmpty(authMode) ? 1 : Integer.valueOf(authMode));
				response.sendRedirect(pathUrl);
			} catch (IOException e) {
				logger.error("扫商品二维码跳转失败前端路径======"+pathUrl);
				logger.error(e.getMessage());
				e.printStackTrace();
			}
		}else{
			try {
				if(StringUtils.isEmpty(storeId) || StringUtils.isEmpty(shopperId) || StringUtils.isEmpty(buyerId)){
					//错误页面路径
					pathUrl = sweepOrderVueUrl+"/#/error";
				}else{
					//判断店铺装修平台配置后首次进入的页面
					pathUrl = authService.getRedirectPath(Integer.valueOf(shopperId),Integer.valueOf(storeId),tableInfoId,buyerId,accessToken,null,null,reserveHexiao,bindType);
				}
				response.sendRedirect(pathUrl);
				logger.info("老版本H5授权之后跳转到VUE判断路径跳转=============="+pathUrl);
			} catch (Exception e1) {
				e1.printStackTrace();
				try {
					response.sendRedirect(pathUrl);
				} catch (IOException e) {
					e.printStackTrace();
				}
				logger.info("老版本H5授权之后跳转到VUE判断路径跳转=============="+e1.getMessage());
			}
		}
	}
	
	/**
	 * 在线订单授权回调后判断跳转路径
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = { "/redirectOnlinePath" })
    @ResponseBody
	public String redirectOnlinePath(HttpServletRequest request,
			HttpServletResponse response) {
	    String bindTypeStr = request.getParameter("bindType");
	    Integer bindType = StringUtils.isNotEmpty(bindTypeStr) ? Integer.valueOf(bindTypeStr) : null;
		//顾客id
		String buyerId = request.getParameter("buyerId");
		//子店铺id
		String storeId = request.getParameter("storeId");
		//主店铺id6
		String shopperId= request.getParameter("shopperId");
		//微信授权后的accessToken
		String accessToken = request.getParameter("accessToken");
		// 预约核销配置
		String reserveHexiao = request.getParameter("reserveHexiao");
		String path="";
		if(StringUtils.isEmpty(storeId) || StringUtils.isEmpty(buyerId) || StringUtils.isEmpty(shopperId)){
			path =sweepOrderVueUrl+"/#/error";
			return path;
		}
		try {
			path = authService.getRedirectOnlinePath(Integer.valueOf(storeId),buyerId,Integer.valueOf(shopperId),accessToken,null,null,reserveHexiao,bindType);
			String url = sweepOrderVueUrl+path;
			response.sendRedirect(url);
			logger.info("在线订单进入VUE路径跳转==============="+url);
		} catch (IOException e) {
			e.printStackTrace();
			logger.error(Utils.log4jDetail(e));
		}
		return null;
	}
	
	/**
	 * 是否关注微信公众号
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = { "/isfollowWeChat" },method=RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "是否关注微信公众号")
	public CoreResponse<String> isfollowWeChat(HttpServletRequest request,
			HttpServletResponse response,@RequestParam(required = true) String openId,
			@RequestParam(required = false) Integer storeId,@RequestParam(required = false) Integer shopId) {
		CoreResponse<String> result = new CoreResponse<String> ();
		// 用户微信id
		if (Utils.isEmpty(openId)) {
			result.setStatusInfo(CoreResponse.StatusInfo.ERROR_40001);
			result.setMsg("获取关注微信公众号信息失败,用户微信id为空");
		}
		// 子店铺id
		if (Utils.isEmpty(storeId)) {
			result.setStatusInfo(CoreResponse.StatusInfo.ERROR_40001);
			result.setMsg("获取关注微信公众号信息失败,子店铺id为空");
		}
		// 主店铺id
		if (Utils.isEmpty(shopId)) {
			result.setStatusInfo(CoreResponse.StatusInfo.ERROR_40001);
			result.setMsg("获取关注微信公众号信息失败,主店铺id为空");
		}
		try {
			result = HttpUtils.doGet(authUrl + "auth/isfollowWeChat.htm?openId="+openId+"&storeId="+storeId+"&shopId="+shopId);
			if (null != result && !Utils.isEmpty(result.getData())) {
				JSONObject jo = JSONObject.parseObject(result == null ? null : result.getData());
				if (jo.getBooleanValue("success")) {
					JSONObject json = jo.getString("json") == null ? null : JSONObject.parseObject(jo.getString("json"));
					result.setStatusInfo(CoreResponse.StatusInfo.SUCCESS);
					result.setData(json+"");
				} else {
					result.setStatusInfo(CoreResponse.StatusInfo.SUCCESS);
					result.setMsg("获取关注微信公众号信息失败");
				}
			}else{
				result.setStatusInfo(CoreResponse.StatusInfo.SUCCESS);
				result.setMsg("获取关注微信公众号信息失败");
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(Utils.log4jDetail(e));
			result.setStatusInfo(CoreResponse.StatusInfo.BUSINESS);
			result.setMsg("获取关注微信公众号信息失败");
		}
		return result;
	}

    /*
     *<pre>
     * 说    明: 获取微信jsSdk token
     * 涉及版本:
     * 创 建 者: YangYangjun
     * 日    期: 2020-03-07 13:47
     *</pre>
     **/
    @RequestMapping(value = "getWxJsSdkSignature", method = RequestMethod.GET)
    @ResponseBody
    @ApiOperation(value = "获取微信jsSdk")
    public CoreResponse<Object> getWxJsSdkSignature(String url) throws Exception {
        CoreResponse<Object> res = new CoreResponse<Object>();
        Object wxJsSdkCache = redisService.getObj("sweep_WxJsSdkSignature");
        if(wxJsSdkCache != null){
            res.setCode(CoreResponse.StatusInfo.SUCCESS.getCode());
            res.setData(wxJsSdkCache);
            return res;
        }
        if(StringUtils.isNotEmpty(url)){
            res.setCode(CoreResponse.StatusInfo.FORBIDDEN.getCode());
            res.setSubMsg("url不能为空");
            return res;
        }
        //TODO wx签名信息待完善
        String appId = "#";
        String secret = "#";
        String jsApiTicket = ""; //密钥验证票参
        String nonceStr =  UUID.randomUUID().toString(); //随机数
        String timestamp = Long.toString(System.currentTimeMillis() / 1000); //时间戳
        //url 调用地址
        String signature = "";//生成秘钥
        //生成验证密文
        jsApiTicket = getJsApiTicket(appId,secret);

        //签名生成参数
        String buildParamsStr = "jsapi_ticket=" + jsApiTicket +
                "&noncestr=" + nonceStr +
                "&timestamp=" + timestamp +
                "&url=" + url;
        System.out.println(buildParamsStr);
        MessageDigest crypt = MessageDigest.getInstance("SHA-1");
        crypt.reset();
        crypt.update(buildParamsStr.getBytes(StandardCharsets.UTF_8));
        signature = byteToHex(crypt.digest());
        HashMap<String,Object> resultMap = new HashMap<>();
        resultMap.put("nonceStr",nonceStr);
        resultMap.put("timestamp",timestamp);
        resultMap.put("url",url);
        resultMap.put("appId", appId);
        resultMap.put("signature",signature);

        res.setCode(CoreResponse.StatusInfo.SUCCESS.getCode());
        res.setData(resultMap);
        //存入redis缓存 2小时更替
        redisService.setObj("sweep_WxJsSdkSignature",resultMap,2L, TimeUnit.HOURS);
        return res;
    }

    /**
     * 密钥生成
     * @return
     */
    private static String getJsApiTicket(String appId,String secret){
        String jsApiTicket = "";
        //token获取地址
        String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token";
        //ticket获取地址
        String ticketUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket";
        //获取token
        HashMap<String, Object> tokenParamsMap = new HashMap<>();
        tokenParamsMap.put("grant_type","client_credential");
        tokenParamsMap.put("appid",appId);
        tokenParamsMap.put("secret",secret);
        String tokenResultStr = HttpUtil.doPost(tokenUrl, tokenParamsMap);
        if(StringUtils.isNotEmpty(tokenResultStr)){
            JSONObject tokenJson = JSONObject.parseObject(tokenResultStr);
            String accessToken = tokenJson.getString("access_token");
            if(StringUtils.isNotEmpty(accessToken)){
                //获取ticket
                HashMap<String, Object> ticketParamsMap = new HashMap<>();
                ticketParamsMap.put("type","jsapi");
                ticketParamsMap.put("access_token",accessToken);
                String ticketResultStr = HttpUtil.doPost(ticketUrl, ticketParamsMap);
                if(StringUtils.isNotEmpty(ticketResultStr)){
                    JSONObject ticketJson = JSONObject.parseObject(ticketResultStr);
                    String ticket = ticketJson.getString("ticket");
                    if(StringUtils.isNotEmpty(ticket)){
                        return ticket;
                    }
                }
            }

        }
        return jsApiTicket;
    }

    private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash) {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }
}
